/*
 * Copyright 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.gruposp2p.dnie.client.ui.widget.dynatable;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.InvocationException;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import org.gruposp2p.dnie.client.dto.DocumentToSignDTO;
import org.gruposp2p.dnie.client.ui.dialogs.DocumentToSignDialog;
import org.gruposp2p.dnie.client.ui.dialogs.ErrorDialog;
import org.gruposp2p.dnie.client.ui.panel.MainPanel;

import java.util.List;

public class UploadedDocumentsWidget extends Composite {

    private static final String NO_CONNECTION_MESSAGE = "Error de conexión !!!";

    private final RowDataAcceptor acceptor = new RowDataAcceptorImpl();
    private final Grid grid;
    private final NavBar navbar = new NavBar();
    private ErrorDialog errorDialog = null;
    private final DockPanel outer = new DockPanel();
    private final DynaTableDataProvider dataprovider = 
    	new UploadedDocumentsDynaTableProvider();;
    private int startRow = 0;

    private class NavBar extends Composite implements ClickHandler {

        public final DockPanel bar = new DockPanel();
        public final Button gotoFirst = new Button("&lt;&lt;", this);
        public final Button gotoNext = new Button("&gt;", this);
        public final Button gotoPrev = new Button("&lt;", this);
        public final Button newDocumentButton = new Button("Nuevo documento", this);
        public final HTML status = new HTML();

        public NavBar() {
            initWidget(bar);
            bar.setStyleName("navbar");
            status.setStyleName("status");
            newDocumentButton.setWidth("180px");
            newDocumentButton.setStyleName("navbarButton");
            HorizontalPanel newDocumentButtonPanel = new HorizontalPanel();
            newDocumentButtonPanel.add(newDocumentButton);
            HorizontalPanel buttons = new HorizontalPanel();
            gotoFirst.setStyleName("navbarButton");
            buttons.add(gotoFirst);
            gotoPrev.setStyleName("navbarButton");
            buttons.add(gotoPrev);
            gotoNext.setStyleName("navbarButton");
            buttons.add(gotoNext);
            bar.add(newDocumentButtonPanel, DockPanel.WEST);
            bar.add(buttons, DockPanel.EAST);
            bar.setCellHorizontalAlignment(buttons, DockPanel.ALIGN_RIGHT);
            bar.add(status, DockPanel.CENTER);
            bar.setVerticalAlignment(DockPanel.ALIGN_MIDDLE);
            bar.setCellHorizontalAlignment(status, HasAlignment.ALIGN_RIGHT);
            bar.setCellVerticalAlignment(status, HasAlignment.ALIGN_MIDDLE);
            bar.setCellWidth(status, "100%");
            // Initialize prev & first button to disabled.
            gotoPrev.setEnabled(false);
            gotoFirst.setEnabled(false);
        }

        public void onClick(ClickEvent event) {
            Object source = event.getSource();
            if (source == gotoNext) {
                startRow += getDataRowCount();
                refresh();
            } else if (source == gotoPrev) {
                startRow -= getDataRowCount();
                if (startRow < 0) {
                	startRow = 0;
                }
                refresh();
            } else if (source == gotoFirst) {
                startRow = 0;
                refresh();
            } else if (source == newDocumentButton) {
            	showNewDocumentDialog();
            }
        }
    }

    public void showNewDocumentDialog() {
        final DocumentToSignDTO signatureData = new DocumentToSignDTO();
        signatureData.type = DocumentToSignDTO.DOCUMENT_TYPE_MANIFEST;
        DocumentToSignDialog signatureDataDialog =
        	new DocumentToSignDialog (signatureData);
        signatureDataDialog.center();
    }
    
    public UploadedDocumentsWidget(int rowCount) {
        grid = new Grid(rowCount,2);
        initWidget(outer);
        grid.setStyleName("table");
        outer.add(navbar, DockPanel.NORTH);
        outer.add(grid, DockPanel.CENTER);
        initTable(rowCount);
        setStyleName("DynaTable-DynaTableWidget");
    }

    public void clearStatusText() {
        navbar.status.setHTML("&nbsp;");
    }

    public void refresh() {
        // Disable buttons temporarily to stop the user from running off the end.
        navbar.gotoFirst.setEnabled(false);
        navbar.gotoPrev.setEnabled(false);
        navbar.gotoNext.setEnabled(false);
        grid.clear();
        setStatusText("");
        grid.setWidget(0, 0, new HTML(MainPanel.INSTANCE.constants.loadingInfoLabel()));
        dataprovider.updateRowData(startRow, grid.getRowCount() - 1, acceptor);
    }

    public void setRowCount(int rows) {
        grid.resizeRows(rows);
    }

    public void setStatusText(String text) {
        navbar.status.setText(text);
    }

    private int getDataRowCount() {
        return grid.getRowCount() - 1;
    }

    private void initTable(int rowCount) {
        // Set up the header row. It's one greater than the number of visible rows.
    	grid.setWidget(0, 0, getTableHeader());
        grid.resizeRows(rowCount + 1);
    }

    private void setStartRow (int startRow) {
        this.startRow = startRow;
    }

    private HorizontalPanel getTableHeader () {
        final HorizontalPanel horizontalPanel = new HorizontalPanel();
        horizontalPanel.setStyleName("TableHeader");
        horizontalPanel.setSpacing(6);
        HTML title = new HTML("Título");
        title.setStyleName("DocumentToSignTableTitleColumn");
        title.addStyleName("DocumentToSignTableItemWidgetTitle");
        horizontalPanel.add(title);
        HTML dateCreated = new HTML("Creado");
        dateCreated.setStyleName("DocumentToSignTableDateCreatedColumn");
        horizontalPanel.add(dateCreated);        
        HTML dateBegin = new HTML("Activo desde");
        dateBegin.setStyleName("DocumentToSignTableDateBeginColumn");
        horizontalPanel.add(dateBegin);
        HTML dateEnd = new HTML("Activo hasta");
        dateEnd.setStyleName("DocumentToSignTableDateEndColumn");
        horizontalPanel.add(dateEnd);        
        return horizontalPanel;
    }

    @Override
    protected void onLoad() {
        refresh();
    }
    
    private class RowDataAcceptorImpl implements RowDataAcceptor {

        List<DocumentToSignDTO> documents;

        public void accept(int startRow, List<DocumentToSignDTO> documentsTosign) {
        	grid.clear();
        	grid.setWidget(0, 0, getTableHeader());
            documents = documentsTosign;
            int destRowCount = getDataRowCount();
            int srcRowCount = 0;
            int destRowIndex = 1; // skip navbar row
            String statusText;
            if (documentsTosign != null) {
                srcRowCount = documents.size();
                for (DocumentToSignDTO document : documents) {
                    UploadedDocumentsTableItemWidget tableWidget =
                        new UploadedDocumentsTableItemWidget (document);
                    //grid.setWidget(destRowIndex, 1, new HTML("destRowIndex: " + destRowIndex));
                    grid.setWidget(destRowIndex, 0, tableWidget);
                    destRowIndex++;
                }
                statusText = (startRow + 1) + " - " + (startRow + srcRowCount);
            } else {
            	statusText = startRow + " - " + (startRow + srcRowCount);
            }
            // Clear remaining table rows.
            boolean isLastPage = false;
            for (; destRowIndex < destRowCount + 1; ++destRowIndex) {
                isLastPage = true;
                grid.clearCell(destRowIndex, 0);
            }
            // Synchronize the nav buttons.
            navbar.gotoNext.setEnabled(!isLastPage);
            navbar.gotoFirst.setEnabled(startRow > 0);
            navbar.gotoPrev.setEnabled(startRow > 0);
            // Update the status message.
            setStatusText(statusText);
        }

        public void failed(Throwable caught) {
            setStatusText("Error");
            if (errorDialog == null) {
                errorDialog = new ErrorDialog();
            }
            if (caught instanceof InvocationException) {
                errorDialog.setText("An RPC server could not be reached");
                errorDialog.setBody(NO_CONNECTION_MESSAGE);
            } else {
                errorDialog.setText("Unexcepted Error processing remote call");
                errorDialog.setBody(caught.getMessage());
            }
            errorDialog.center();
        }

        public void insertNewElement() {
            startRow = 0;
            refresh();
        }

        public void deleteElement() {
            refresh();
        }

    }
    
}